#coding=utf-8
import sys #要重新载入sys。因为 Python 初始化后会删除 sys.setdefaultencoding 这个方 法
reload(sys)
sys.setdefaultencoding('utf-8')

from XMLGenerator.T_XML import T_XML
from ExcelReader.RowGenerator import BaseRowGenerator

from pymongo import MongoClient
import xlrd

import os
import os.path
from common import md5
import traceback
import shutil
from HTGenerator.HTBaseGenerator import *

def error(msg):
    sys.stderr.write('%s\n'%msg)
    raise Exception(msg)

def _print_table_name(data):
    #打印所有的工作表名
    for table_name in data.sheet_names():
        print table_name
def _print_first_table_name(data):
    #打印第一个工作表的名字
    print '####  %s   ###'%data.sheet_names()[0]

def _print_row_value(row_value):
    #读取到的类型可能非 unicode类型 所以要判断、转换
    des = ''
    for value in row_value:
        if type(value) != unicode:
            value = str(value)
        if value == '':
            value = 'None'
        des = des + ' ' + value
    print des

def _file_name(file_path):
    file_name = os.path.basename(file_path)
    strs = file_name.split('.')
    return strs[0]

class JobTitleRowGenerator(BaseRowGenerator):
    def __init__(self, row_value):
        super(JobTitleRowGenerator, self).__init__(row_value)

    def collect_useful_data(self):
        levels = 0

        level_titles = {
            '二级职位':1,
            '三级职位':1,
            '四级职位':1,
        }

        for cell in self.inited_row_value:
            #comment_by_lang, 再严格一些, 后面很多逻辑都依赖于此，后期尽量对文件首先按规定格式检查下
            if cell in level_titles:
                levels += 1
            else:
                break
        self.job_levels = levels

    def __str__(self):
        return ' '.join(self.inited_row_value)


class SpecailClauseOperationRow(BaseRowGenerator):
    def __init__(self, row_value ,job_levels):
        self.job_levels = job_levels
        self.job_types = []

        super(SpecailClauseOperationRow, self).__init__(row_value)

    #提取出来后返回True，否则返回False
    def collect_useful_data(self):
        # print self.inited_row_value
        try:
            for rol in range(self.job_levels):
                if rol == self.job_levels-1:
                    self.job = self.inited_row_value[rol]
                else:
                    self.job_types.append(self.inited_row_value[rol])
            '''
            暂时先这样处理，后面会根据标题确定数据类型
            '''
            self.note = self.inited_row_value[self.job_levels]
            self.operation_name = self.inited_row_value[self.job_levels+1]
            self.operation_object = self.inited_row_value[self.job_levels+2]
            self.operation_content = self.inited_row_value[self.job_levels+3]
            self.clause_location = self.inited_row_value[self.job_levels+5]
            self.special_clause_id = self.inited_row_value[self.job_levels+6]
            self.special_clause_editable = self.inited_row_value[self.job_levels+8]
            self.limit_number = self.inited_row_value[self.job_levels+9]

        except Exception,e:
            error('ReadDataError:%s'%('|'.join(['%s'%item for item in self.row_value])))
            self.isCollected = False
        self.isCollected = True

    def check_update_useful_value(self, content):


        if self.operation_object == '附件':
            self.operation_object_type = OPERATION_TYPE_APPENDIX
        elif self.operation_object == '一级条款':
            self.operation_object_type = OPERATION_TYPE_FIRST_LEVEL
        elif self.operation_object == '二级条款':
            self.operation_object_type = OPERATION_TYPE_SECOND_LEVEL
        elif self.operation_object == '三级条款':
            self.operation_object_type = OPERATION_TYPE_THIRD_LEVEL
        else:
            error("ERROR:%s操作对象无效" % ' '.join([str(item) for item in self.inited_row_value]))
            return False

        if self.operation_name == "增加":
            self.operation_type = OPERATION_ADD
        elif self.operation_name == "替换":
            self.operation_type = OPERATION_REPLACE
        elif self.operation_name == "删除":
            self.operation_type = OPERATION_DELETE
        else:
            error("ERROR:%s操作方式无效" % self.operation_name)
            return False

        types = [OPERATION_ADD, OPERATION_REPLACE]
        if self.operation_type in types and  self.operation_object_type != OPERATION_TYPE_APPENDIX:
            if self.special_clause_id is None:
                error("ERROR:%s无法找到条款ID" % self.job)
                return False

        self.content = content
        return True

    #将条款转化为xml
    def _content2xml(self,content):
        pass


    def __str__(self):
        try:
            return "%d %s %s %s %s %s %s %s %s %s"%(self.operation_object_type, str(self.job_types), str(self.job), str(self.note), str(self.operation_name), str(self.operation_object), str(self.clause_location), str(self.special_clause_id), str(self.special_clause_editable), str(self.limit_number))
            # return str(self.job) + " " + str(self.note) + " " + str(self.operation_name) + " " + str(self.operation_object) + " " + str(self.clause_location) + " " + str(self.special_clause_id) + str(self.special_clause_editable) + str(self.limit_number)
        except:
            return 'SpecailClauseOperationRow object has no attribute'


class ContractGenerator(HTBaseGenerator):
    def __init__(self, special_rows, industry_name, generate_file_type ,ht_set_type, original_contract_file, saved_dir):

        self.jobid2hts = {}
        super(ContractGenerator, self).__init__(special_rows, industry_name, generate_file_type, ht_set_type, original_contract_file, saved_dir)
    def init_data(self):
        for special_row in self.special_rows:
            job_identity = "%s_%s" %(self.industry_name, special_row.job)
            job_id = md5(job_identity)
            self.jobid2_industy_job[job_id] = job_identity
            self.jobid2hts[job_id] = [HT_TYPE_CONTRACT,HT_TYPE_EMPLOYEE]

    def get_attrib(self, special_row):
        attrib = {}
        if special_row.note is not None:
            attrib = {'note': special_row.note}
        return attrib

    def deal_appendix_row(self, special_row, xml_generator):
        appendix_name = None
        if special_row.operation_content == '竞业限制协议':
            appendix_name = HT_TYPE_COMPETITION
        if special_row.operation_content == '保密协议':
            appendix_name = HT_TYPE_SECRET
        if special_row.operation_content == '劳动合同':
            appendix_name = HT_TYPE_CONTRACT
        if special_row.operation_content == '员工手册':
            appendix_name = HT_TYPE_EMPLOYEE

        if appendix_name:
            job_identify = "%s_%s" %(self.industry_name, special_row.job)
            job_id = md5(job_identify)
            contracts = self.jobid2hts[job_id]

            if special_row.operation_type == OPERATION_ADD:
                contracts.append(appendix_name)
            if special_row.operation_type == OPERATION_DELETE:
                contracts.remove(appendix_name)

    '''
    暂时在这里生成行业-职位对应的所有的合同、约束文件
    '''

    def write_to_all_map_file(self, file_name, employee_map):
        map_file = '%s/%s' % (self.saved_dir, file_name)

        fo = open(map_file, mode='wb')

        for job_id, hts in self.jobid2hts.items():
            writing_items = []
            job_identity = self.jobid2_industy_job[job_id]
            industry_job = job_identity.split('_')
            industry = None
            job = None
            if len(industry_job) == 2:
                industry = industry_job[0]
                job = industry_job[1]
            if industry is None or job is None:
                error("Error:%s 写入到 %s 时出错" % job_identity, map_file)
                continue
            writing_items.append(industry)
            writing_items.append(job)
            writing_items.append(self.ht_set_type)

            all_types = [HT_TYPE_CONTRACT, HT_TYPE_EMPLOYEE, HT_TYPE_COMPETITION, HT_TYPE_SECRET]

            for ht in all_types:
                if ht in hts:
                    if ht == HT_TYPE_CONTRACT:
                        contract_file = self.jobid2htfile[job_id]
                        writing_items.append(contract_file)
                    elif ht == HT_TYPE_EMPLOYEE:

                        e_id = md5(industry+'_'+job+'_'+self.ht_set_type)
                        file_name = employee_map.get(e_id)
                        if file_name is not None:
                            writing_items.append(file_name)
                        else:
                            ht_file = ht + '.xml'
                            writing_items.append(ht_file)
                    else:
                        ht_file = ht + '.xml'
                        writing_items.append(ht_file)
                else:
                    writing_items.append('0')


            constraints = ['constraint.xml', '0', '0', '0']
            for constraint in constraints:
                writing_items.append(constraint)

            writing_items.append("\n")
            fo.write(" ".join(writing_items))

        fo.close()


'''
row_value 为行数据
row 表示行号
merged_cells_map  合并单元格的值,字典格式 key 为(row, col) value 为单元格value
'''
def update_row_value(row_value, row, merged_cells_map):

    new_data = [];

    for index, value in enumerate(row_value):
        if type(value) == unicode:
            value = str(value)
            if value == "":
                cell_loc = "(%d,%d)" % (row, index)

                if cell_loc in merged_cells_map.keys():
                    value = merged_cells_map[cell_loc]

        new_data.append(value)
    return new_data

'''
处理被合并的单元格的数据 给被合并的单元格赋予同样的值
'''

def get_merged_cells_map(table):
    merged_cells_map = {}
    for crange in table.merged_cells:
        rlo, rhi, clo, chi = crange
        # print rlo, rhi, clo, chi
        for r in range(rlo, rhi):
            for c in range(clo, chi):
                cell = table.cell(r,c)
                value = cell.value
                cell_loc = "(%d,%d)"%(r,c)
                if value == "":
                    #排除合并单元格区域的第一行
                    if r > rlo:
                        top_cell_loc = "(%d,%d)"%(r-1,c)
                        top_cell_value = merged_cells_map[top_cell_loc]
                        value = top_cell_value
                merged_cells_map[cell_loc] = value
    return merged_cells_map

def get_employee_map(file_path):
    isExist = os.path.exists(file_path)
    if not isExist:
        print 'ERROR:%s该文件不存在'%file_path
        return {}
    fo = open(file_path, 'r')
    id2employeefile = {}
    for line in fo:
        line = line.strip()
        elements = line.split()
        employee_file = elements.pop()
        ef_id = md5('_'.join(elements))
        id2employeefile[ef_id] = employee_file
        print '_'.join(elements), employee_file
    return id2employeefile


def read_industry_special_excel_file(file_path, industry_name,ht_set_type, saved_dir, original_contract_file):
    isExist = os.path.exists(file_path)
    if not isExist:
        error('ERROR:%s该文件不存在'%file_path)
        return

    '''
    读取excel数据
    '''
    data = xlrd.open_workbook(file_path)
    # _print_first_table_name(data)
    print '########    %s     #########' % industry_name
    '''
    后期加上合法性检查
    '''
    if len(data.sheets()) == 0:
        error('ERROR::%s该文件中不包含表'%file_path)
        return

    table = data.sheets()[0]

    #先确定该表有多少个职位级别
    first_row_value = table.row_values(0)
    if first_row_value is not None:
        job_title_row = JobTitleRowGenerator(first_row_value)
    else:
        error('ERROR::%s该文件第一个表中无数据'%file_path)
        return

    if job_title_row.job_levels == 0:
        error('ERROR::%s该文件第一个表第一行不包含列信息%s'%(file_path, job_title_row))
        return
    levels = job_title_row.job_levels


    '''
    处理被合并的单元格的数据 给被合并的单元格赋予同样的值
    '''
    merged_cells_map = get_merged_cells_map(table)

    '''
    更新数据
    '''
    mongo_client = MongoClient(host='127.0.0.1', port=27017, document_class=dict, tz_aware=None, connect=None)
    db = mongo_client["CLAUSES"]
    col = db["special_clauses"]

    special_rows = []
    for row_index in range(1,table.nrows):
        row_value = table.row_values(row_index)
        row_value = update_row_value(row_value, row_index, merged_cells_map)

        special_row = SpecailClauseOperationRow(row_value, levels)
        content = None
        if not special_row.isCollected:
            raise Exception('收集有用数据失败%s' % special_row)
            continue

        if special_row.special_clause_id:
            #根据ID找到条款
            # print "INFO:type1 = %s type2 = %s _id = %s" % (special_row.job_type_one, special_row.job_type_two, special_row.special_clause_id)
            repr = col.find_one({'_id':special_row.special_clause_id})

            content = repr['content']
        if special_row.check_update_useful_value(content) == True:
            special_rows.append(special_row)
        else:
            raise Exception("改行数据不合法%s" % special_row)

    mongo_client.close()

    '''
    生成完整的xml文档
    '''
    generator = ContractGenerator(special_rows, industry_name, "contract" ,ht_set_type, original_contract_file, saved_dir)
    generator.generate_contract()

    '''
    读取employee_map
    '''
    employee_map = get_employee_map('%s/employee_map.txt' % saved_dir)

    #如果没有该文件，copy employee.xml 到各目录下
    if len(employee_map) == 0:
        shutil.copy('Contract/employee.xml', saved_dir)

    shutil.copy('Contract/competition.xml', saved_dir)
    shutil.copy('Contract/secret.xml', saved_dir)

    generator.write_to_all_map_file("category_map.txt", employee_map)
    # for key, value in generator.jobmd5_contracts_map.items():
    #     print key, value

if __name__ == '__main__':
    industry_file_paths = ['Contract/catering/catering.xlsx','Contract/internet/internet.xlsx','Contract/culture/culture.xlsx','Contract/cloth/cloth.xlsx','Contract/education/education.xlsx','Contract/retail/retail.xlsx','Contract/travel/travel.xlsx','Contract/construction/construction.xlsx','Contract/finance/finance.xlsx','Contract/science/science.xlsx','Contract/humanResource/humanResource.xlsx']

    industry_dir_name_maps = {
        'Contract/catering/catering.xlsx':'餐饮业','Contract/internet/internet.xlsx':'互联网','Contract/culture/culture.xlsx':"文化传媒",'Contract/cloth/cloth.xlsx':"服装设计",'Contract/education/education.xlsx':"教育培训",'Contract/retail/retail.xlsx':"零售类",'Contract/travel/travel.xlsx':"旅游",'Contract/construction/construction.xlsx':"建筑",'Contract/finance/finance.xlsx':"金融",'Contract/science/science.xlsx':"科技及制造类",'Contract/humanResource/humanResource.xlsx':"人力资源类"
    }



    for index, file_path in enumerate(industry_file_paths):
        # if index == 0:
        industry_name = industry_dir_name_maps[file_path]
        subDirs = file_path.split('/')

        saved_dir = '/'.join([subDirs[0], subDirs[1]])
        read_industry_special_excel_file(file_path, industry_name, "劳动合同", saved_dir, 'Contract/contract.xml')
